﻿using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using MugenMvvmToolkit.Models;

namespace MugenMvvmToolkit.Interfaces.ViewModels
{
    /// <summary>
    ///     Represent the interface for editable view model.
    /// </summary>
    public interface IEditableViewModel : IValidatableViewModel
    {
        /// <summary>
        ///     Gets the type of model.
        /// </summary>
        [NotNull]
        Type ModelType { get; }

        /// <summary>
        ///     Gets the value which indicates that is the new entity or not.
        /// </summary>
        bool IsNewRecord { get; }

        /// <summary>
        /// Gets a value indicating whether the entity has changes.
        /// </summary>
        bool HasChanges { get; }

        /// <summary>
        /// Gets a value indicating whether the entity is initialized.
        /// </summary>
        bool IsEntityInitialized { get; }

        /// <summary>
        ///     Gets the edited entity.
        /// </summary>
        object Entity { get; }

        /// <summary>
        ///     Initializes the specified entity to edit.
        /// </summary>
        /// <param name="entity">The specified entity to edit.</param>
        /// <param name="isNewRecord">
        ///     If <c>true</c> is new entity;otherwise <c>false</c>.
        /// </param>
        void InitializeEntity([NotNull]object entity, bool isNewRecord);

        /// <summary>
        ///     Applies the changes of entity.
        /// </summary>
        /// <returns>A series of instances of <see cref="IEntityStateEntry"/>.</returns>
        [NotNull]
        IList<IEntityStateEntry> ApplyChanges();

        /// <summary>
        ///     Cancels the changes of entity.
        /// </summary>
        /// <returns>An instance of object.</returns>
        [NotNull]
        object CancelChanges();

        /// <summary>
        ///     Occurs at the end of initialization the entity.
        /// </summary>
        event EntityHandler<object> EntityInitialized;

        /// <summary>
        ///     Occurs at the end of apply entity changes.
        /// </summary>
        event EntityHandler<IList<IEntityStateEntry>> ChangesApplied;

        /// <summary>
        ///     Occurs at the end of cancel entity changes.
        /// </summary>
        event EntityHandler<object> ChangesCanceled;
    }

    /// <summary>
    ///     Represent the interface for editable view model.
    /// </summary>
    public interface IEditableViewModel<T> : IEditableViewModel where T : class
    {
        /// <summary>
        ///     Gets the edited entity.
        /// </summary>
        new T Entity { get; }

        /// <summary>
        ///     Initializes the specified entity to edit.
        /// </summary>
        /// <param name="entity">The specified entity to edit.</param>
        /// <param name="isNewRecord">
        ///     If <c>true</c> is new entity;otherwise <c>false</c>.
        /// </param>
        void InitializeEntity([NotNull]T entity, bool isNewRecord);

        /// <summary>
        ///     Cancels the changes of entity.
        /// </summary>
        /// <returns>An instance of object.</returns>
        [NotNull]
        new T CancelChanges();

        /// <summary>
        ///     Occurs at the end of initialization the entity.
        /// </summary>
        new event EntityHandler<T> EntityInitialized;

        /// <summary>
        ///     Occurs at the end of cancel entity changes.
        /// </summary>
        new event EntityHandler<T> ChangesCanceled;
    }
}